package com.wh.usercenter3.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wh.usercenter3.constant.CodeConstant;
import com.wh.usercenter3.exception.BaseException;
import com.wh.usercenter3.mapper.UserMapper;
import com.wh.usercenter3.mapper.UserTeamMapper;
import com.wh.usercenter3.pojo.Team;
import com.wh.usercenter3.pojo.User;
import com.wh.usercenter3.pojo.UserTeam;
import com.wh.usercenter3.pojo.dto.QueryTeamDto;
import com.wh.usercenter3.pojo.dto.TeamQueryDto;
import com.wh.usercenter3.pojo.vo.NewTeamVo;
import com.wh.usercenter3.pojo.vo.PageDataVo;
import com.wh.usercenter3.service.TeamService;
import com.wh.usercenter3.mapper.TeamMapper;
import com.wh.usercenter3.service.UserService;
import com.wh.usercenter3.service.UserTeamService;
import com.wh.usercenter3.util.TeamUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author 18141
* @description 针对表【team(队伍)】的数据库操作Service实现
* @createDate 2025-02-25 15:42:35
*/
@Service
public class TeamServiceImpl extends ServiceImpl<TeamMapper, Team>
    implements TeamService{


    @Resource
    private UserTeamService userTeamService;

    @Resource
    private UserService userService;

    @Resource
    private TeamMapper teamMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private UserTeamMapper userTeamMapper;

    /**
     * 创建队伍
     * @param team
     * @param request
     * @return
     */
    @Transactional // sql事务处理
    @Override
    public NewTeamVo teamAdd(Team team, HttpServletRequest request) {
        // 校验逻辑
        TeamUtil.dateCheck(team,request);
        // 插入表
        if (!this.save(team)) throw new BaseException(CodeConstant.SERVICE_ERR, "插入team记录失败");
        UserTeam userTeam = new UserTeam();
        userTeam.setJoinTime(LocalDateTime.now());
        userTeam.setUserId(team.getUserId());
        userTeam.setTeamId(team.getId());
        if (!userTeamService.save(userTeam)) throw new BaseException(CodeConstant.SERVICE_ERR, "插入user-team记录失败");
        //> 3. 返回视图类
        NewTeamVo newTeamVo = new NewTeamVo();
        BeanUtils.copyProperties(team,newTeamVo);
        return newTeamVo;
    }

    /**
     *  更新队伍逻辑
     * @param team
     * @param request
     */
    @Override
    @Transactional
    public void teamUpdate(Team team, HttpServletRequest request) {
        // 校验逻辑
        TeamUtil.dateCheck(team,request);
        // TeamId要进行存在校验
        QueryWrapper<Team> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", team.getId());
        if (this.count(queryWrapper)<1)
        throw new BaseException(CodeConstant.CLIENT_ERR, "队伍不存在");
        // 修改数据库
        if (!this.updateById(team)) throw new BaseException(CodeConstant.SERVICE_ERR, "修改队伍信息失败");
    }

    /**
     * 模糊查询
     * @param dto
     * @param loginUser
     * @return
     */
    @Override
    public List<NewTeamVo> teamList(QueryTeamDto dto, User loginUser) {
        String content = dto.getContent();
        // 判空 - 尤其注意content字段不能为空 - content不超过20个符号
        if (content.isEmpty() || content.length()>20)
            throw new BaseException(CodeConstant.CLIENT_ERR, "查询内容为空或太长");
        // 动态sql
        List<Team> teams = teamMapper.teamQuery(dto);
        if (teams==null) throw new BaseException(CodeConstant.SERVICE_ERR, "查询失败");
        // 脱敏
        return teams
                .stream()
                .map(team -> {
                    NewTeamVo newTeamVo = new NewTeamVo();
                    BeanUtils.copyProperties(team, newTeamVo);
                    return newTeamVo;
                }).collect(Collectors.toList());
    }



    /**
     * 分页查询逻辑
     * @param dto 包装类
     * @return 视图类集合
     */
    @Override
    public PageDataVo<List<NewTeamVo>> pageQuery(TeamQueryDto dto) {
        // 条件
        QueryWrapper<Team> wrapper = new QueryWrapper<>();
        String dtoName = dto.getName();
        Long userId = dto.getUserId();
        if (StringUtils.isNotEmpty(dtoName)) {
            wrapper.like("name", dtoName);
        }
        if (userId != null && userId != 0) {
            wrapper.eq("userId", userId);
        }
        // 查找
        Page<Team> result = teamMapper.selectPage(new Page<>(dto.getPageNum(), dto.getPageSize()), wrapper);
        if (result == null) {
            throw new BaseException(CodeConstant.SERVICE_ERR, "无数据");
        }
        List<Team> teams = result.getRecords();
        // 脱敏
        List<NewTeamVo> newTeamVoList = teams.stream().map(team -> {
            NewTeamVo newTeamVo = new NewTeamVo();
            BeanUtils.copyProperties(team, newTeamVo);
            return newTeamVo;
        }).collect(Collectors.toList());
        // 创建分页数据类
        PageDataVo<List<NewTeamVo>> pageDataVo = new PageDataVo<>();
        pageDataVo.setRecords(newTeamVoList);
        pageDataVo.setSize(result.getSize());
        pageDataVo.setNum(dto.getPageNum());
        pageDataVo.setTotal(result.getPages());

        return pageDataVo;
    }

    /**
     * 加入队伍实现
     *
     * @param userId
     * @param teamId
     * @param password
     * @return
     */
    @Override
    public boolean teamJoin(long userId, long teamId, String password) {
        //- 取出对应的user和team
        User user = userMapper.selectById(userId);
        Team team = teamMapper.selectById(teamId);
        //- 判断有没有对应的user和team
        if (user == null || team == null)
            throw new BaseException(CodeConstant.CLIENT_ERR, "参数有误，userId或teamId不存在");
        //- 判断team的时间是否过期
        LocalDateTime expireTime = team.getExpireTime();
        if (expireTime.isBefore(LocalDateTime.now()))
            throw new BaseException(CodeConstant.CLIENT_ERR, "该队伍时间过期");
        //- 判断team的状态是否为公开或者加密，加密需要密码
        Integer status = team.getStatus();
        if (status == 1) throw new BaseException(CodeConstant.CLIENT_ERR, "该队伍为私密队伍");
        if (status == 2) {
            if (StringUtils.isBlank(password)) {
                throw new BaseException(CodeConstant.CLIENT_ERR, "需要密码");
            } else {
                if (!password.equals(team.getPassword())) {
                    throw new BaseException(CodeConstant.CLIENT_ERR, "密码错误");
                }
            }
        }
        //- 通过userTeam关系表，取出当前队伍的人数
        List<Long> userIds = userTeamMapper.getUsersIdByTeamId(teamId);
        //- 判断team人数是否达到上限
        if (userIds.size()>=team.getMaxNum()) throw new BaseException(CodeConstant.CLIENT_ERR, "队伍已满");
        //- 判断user是否加入过team
        for (Long id : userIds) {
            if (userId == id) throw new BaseException(CodeConstant.CLIENT_ERR, "请勿重复加入队伍");
        }
        // userTeam表新增记录
        UserTeam userTeam = new UserTeam();
        userTeam.setJoinTime(LocalDateTime.now());
        userTeam.setTeamId(teamId);
        userTeam.setUserId(userId);
        if (userTeamMapper.insert(userTeam)!=1)
            throw new BaseException(CodeConstant.SERVICE_ERR, "新增加入队伍记录失败");
        return true;
    }

    /**
     *  退出队伍逻辑
     * @param userId
     * @param teamId
     * @return
     */
    @Override
    @Transactional
    public boolean teamQuit(long userId, long teamId) {
        //- 提取team信息，提取userId记录
        Team team = teamMapper.selectById(teamId);
        User user = userMapper.selectById(userId);
        //- 判断user和team存在
        if (team == null || user ==null){ throw new BaseException(CodeConstant.CLIENT_ERR, "队伍或者用户不存在");}
        //- 提取user-team表：返回userId列表，且按照加入时间正序排序
        List<Long> users = userTeamMapper.getUsersIdByTeamId(teamId);
        //- 如果只有一个人就解散队伍
        if (users.size() == 1) {
            Long user1 = users.get(0);
            if (user1 != userId) {
                throw new BaseException(CodeConstant.CLIENT_ERR, "该用户未加入队伍");
            } else {
                if (!userTeamService.remove(new QueryWrapper<UserTeam>().eq("userId", userId).eq("teamId",teamId)) || teamMapper.deleteById(teamId) < 1) {
                    throw new BaseException(CodeConstant.SERVICE_ERR, "退出队伍失败");
                } else {
                    return true;
                }
            }

        }
        //- 如果user是队长就将队长给最早进入的队员
        if (userId == team.getUserId()) {
            team.setUserId(users.get(1));
            // 更新队伍信息
            // 删除当前user加入队伍记录
            if (teamMapper.updateById(team) < 1 || userTeamMapper.deleteById(userId) < 1) {
                throw new BaseException(CodeConstant.SERVICE_ERR, "退出队伍失败");
            }else return true;
        }
        //- 判断user是否是队员
        for (Long uId : users) {
            if (uId == userId) {
                if (!userTeamService.remove(new QueryWrapper<UserTeam>().eq("userId", userId).eq("teamId",teamId))) {
                    throw new BaseException(CodeConstant.SERVICE_ERR, "退出队伍失败");
                } else return true;
            }
        }
        // 循环结束没有user
        return false;
    }

    /**
     * 删除队伍
     * @param teamId
     * @param userId
     * @return
     */
    @Override
    @Transactional
    public boolean teamDel(long teamId, long userId) {
        //- 提取team信息，提取userId记录
        Team team = teamMapper.selectById(teamId);
        User user = userMapper.selectById(userId);
        //- 判断user和team存在
        if (team == null || (userId!=0&&user ==null)){ throw new BaseException(CodeConstant.CLIENT_ERR, "队伍或者用户不存在");}
        //判断是不是队长
        if (userId!=team.getUserId()&&userId!=0) throw new BaseException(CodeConstant.CLIENT_ERR, "不是队长无权限删除队伍");
        // 删除记录team user-team
        QueryWrapper<UserTeam> wrapper = new QueryWrapper<>();
        wrapper.eq("teamId", teamId);
        if (teamMapper.deleteById(teamId) < 1 || userTeamMapper.delete(wrapper) < 1)
            throw new BaseException(CodeConstant.SERVICE_ERR, "删除记录失败");
        return true;
    }

}




